package com.geeke.utils;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Random;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Hex;

public class AesUtils {
    
    private static final String ALGORITHM_CBC = "AES/CBC/PKCS5Padding";
    private static final String ALGORITHM_TYPE = "AES";
    // private static final String KEY = "1234567890000000";       // 十六位十六进制数作为密钥
    // private static final String IV = "1234567890000000";        // 十六位十六进制数作为密钥偏移量
    private static final String UTF_8 = StandardCharsets.UTF_8.name();

    private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();

    
    /**
     * 加密
     * @param text 明文
     * @return 返回密文
     * @throws Exception
     */
    public static String encrypt(String text, String key, String iv) throws Exception {
        // 获取实例
        Cipher cilper = Cipher.getInstance(ALGORITHM_CBC);
        // 创建 加密的规则

        SecretKey secretKey = new SecretKeySpec(key.getBytes(UTF_8), ALGORITHM_TYPE);
        // 初始化加解密对象，设置key，和加密规则/解密规则
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(UTF_8));
        // cilper.init(Cipher.DECRYPT_MODE,secretKey);
        cilper.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
        // cilper.init(Cipher.DECRYPT_MODE,secretKey);

        byte[] doFinal = cilper.doFinal(text.getBytes(UTF_8));

        // 对数据进行Base64编码
        String encode = Base64.getEncoder().encodeToString(doFinal);

        return encode;
    }

    /**
     * 解密
     * @param encodetext 密文
     * @return 返回原文
     * @throws Exception
     */
    public static String dencrypt(String encodetext, String key, String iv) throws Exception {

        // 获取实例
        Cipher cilper = Cipher.getInstance(ALGORITHM_CBC);
        // 创建 加密的规则
        SecretKey secretKey = new SecretKeySpec(key.getBytes(UTF_8), ALGORITHM_TYPE);
        // 初始化加解密对象，设置key，和加密规则/解密规则
        // cilper.init(Cipher.ENCRYPT_MODE, secretKey);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(UTF_8));
        // cilper.init(Cipher.DECRYPT_MODE,secretKey);
        cilper.init(Cipher.DECRYPT_MODE,secretKey, ivParameterSpec);

        byte[] doFinal = cilper.doFinal(Base64.getDecoder().decode(encodetext));
        return new String(doFinal, UTF_8);
    }

    /**
     *  通过key生成指定长度的可以
     * @param key
     * @return
     */
    private static SecretKey generatorKey(String key)throws  Exception{
        // 创建keygenerator对象，可以根据传入的key生成一个指定长度的key
        KeyGenerator keyGenerator =KeyGenerator.getInstance(ALGORITHM_CBC);
        // 初始化 secureRandom，并指定生成指定长度key的算法
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");

         secureRandom.setSeed(key.getBytes(UTF_8));
         keyGenerator.init(128,secureRandom);
         SecretKey secretKey = keyGenerator.generateKey();
        // 这里是通过秘钥获取，加密串
        byte[] encoded = secretKey.getEncoded();
        System.out.println(Hex.encodeHexString(encoded));

        return  secretKey;
    }

    /**
     * 产生随机的16位16进制字符串
     * @return
     */
    public static String  generateKey() {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 16; i++) {
            sb.append(HEX_DIGITS[random.nextInt(16)]);
        }

        return sb.toString();
    }


    public static void main(String[] args) throws Exception {
    //    String text = "测试11";
    //    String encrypt = encrypt(text, "1234567890000000", "1234567890000000");
    //    System.out.println(encrypt);
    //    System.out.println("解密" + dencrypt(encrypt, "1234567890000000", "1234567890000000"));
      // generatorKey("123");

      String key = generateKey();
      System.out.println("key:" + key);
    }

}
